home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
screen
/
scrollk.asm
< prev
next >
Wrap
Assembly Source File
|
1983-07-12
|
8KB
|
233 lines
TITLE SCROLLK.COM -- DOS RESIDENT SCROLL LOCK CONTROL
PAGE 60,132
COMMENT* This program provides scrolling control of the video display with
the Scroll Lock key. Assemble, Link, and convert the EXE file to a
COM program. Run the program once on system boot-up then the Scroll
Lock key can be used to toggle scrolling on and off. If scroll lock
is ON, the screen will pause after 23 continuous lines are displayed.
Press the Left shift key to scroll another 23 lines or the Right
shift key to scroll one line; or press Scroll Lock again to turn OFF
the lock and the screen will scroll uninterrupted.*
;----------------------------------------------------------------------------;
;This program intercepts calls to the VIDEO_IO routines. Commands to scroll
;the screen will be intercepted; all others passed through. This routine is
;attached to DOS.
;
;Program by John Socha, 'Softalk', May 1983, pp. 38-49
;
;keyed in by Lee M Buck, Arlington VA
;
;----------------------------------------------------------------------------;
;----------------------------------------------------------------------------;
;Interrupt vectors for video and keyboard routines
;----------------------------------------------------------------------------;
VECTORS SEGMENT AT 0
ORG 10H*4
VIDEO_INT LABEL DWORD
ORG 16H*4
KEYBOARD_INT LABEL DWORD
VECTORS ENDS
;----------------------------------------------------------------------------;
;ROM BIOS data area for keyboard
;
;Contents of KB_FLAG - bits 7 to 0
;<--- --- --- --- --- --- --- --->
; ^INS_STATE ^NUM_STATE ^ALT_SHIFT ^LEFT_SHIFT
; ^CAPS_STATE ^SCROLL_STATE ^CTL_STATE ^RIGHT_SHIFT
;----------------------------------------------------------------------------;
ROM_BIOS_DATA SEGMENT AT 40H
ORG 17H
KB_FLAG DB ? ;Bit 4 set for scroll lock
ROM_BIOS_DATA ENDS
;----------------------------------------------------------------------------;
;Initialize vectors and attach to DOS
;----------------------------------------------------------------------------;
CSEG SEGMENT PARA
ASSUME CS:CSEG
ORG 100H ;Set starting point for COM file
BEGIN: JMP INIT_VECTORS ;Initialize INT 10H and attach to DOS
;----------------------------------------------------------------------------;
;These memory locations store the addresses of the ROM routines for video and
;keyboard I/O routines
;----------------------------------------------------------------------------;
ROM_VIDEO_IO DD ;Address of the ROM routines
ROM_KEYBOARD_IO DD
SCROLL_COUNT DB 0 ;Lines scrolled since last pause
LAST_LOCK_STATE DB 0 ;0 if scrl lock off last time checked
MAX_LINES DB 23 ;Scroll by 23 lines, leaving one old
;line at top before pausing
LAST_LINE DB ;Last line cursor was on
;----------------------------------------------------------------------------;
;This routine intercepts all calls to the VIDEO_IO routine in ROM.
;Scroll Lock:
; OFF This routine passes control directly to the ROM BIOS
; routine.
; ON Functions other than SCROLL UP or SCROLL DOWN are
; passed directly to the ROM routines. Otherwise, this
; routine increments the scroll count and checks to see
; if it exceeds the page size of 23 lines (MAX_LINES).
; If so, loop until either shift key pressed.
; Left shift allows scroll of whole window
; Right shift scrolls one line.
;--------------------------------------------------------------------------;
INTERCEPT_VIDEO PROC FAR
ASSUME CS:CSEG
STI ;Turn on interrupts again
PUSH DS ;Save registers used
PUSH BX
PUSH AX
ASSUME DS:ROM_BIOS_DATA
MOV BX,ROM_BIOS_DATA
MOV DS,BX
MOV AL,KB_FLAG ;Check state of scroll lock key
AND AL,10H ;Isolate scroll lock bit
ASSUME DS:CSEG
MOV BX,CS ;Data segment for variables (above)
MOV DS,BX
CMP AL,LAST_LOCK_STATE
JE UN_CHANGED ;Scroll lock key hasn't changed
MOV BL,MAX_LINES ;Scroll lock key has changed, set to
MOV SCROLL_COUNT,BL ;MAX_LINES to stop scrolling
MOV LAST_LOCK_STATE,AL ;Save the new scroll lock state
PUSH CX ;Now read current cursor position and
PUSH DX ;save in LAST_LINE so SCROLLK won't
PUSH AX ;freeze in the middle of a line
MOV AH,3
MOV BH,0
PUSHF
CALL ROM_VIDEO_IO ;This is a pseudo INT 10H call to BIOS
MOV LAST_LINE,DH ;to find old cursor position and save
POP AX ;in LAST_LINE. (see Tech. Ref. A-43)
POP DX
POP CX
UN_CHANGED:
XCHG AX,BX ;Recover function (AH) and retain scroll lock
POP AX
OR BL,BL ;Is scroll lock on?
JZ TO_VIDEO_IO ;No, jump to the ROM VIDEO_IO routine
;-----------------------;
;Scroll Lock ON ;
;-----------------------;
CMP AH,2 ;Check for SET CURSOR POSITION function
JNE NOPE
CMP DH,LAST_LINE ;Is the cursor being moved to the next line?
MOV LAST_LINE,DH ;Save new cursor line
JLE TO_VIDEO_IO ;No, jump to ROM routine
JMP SHORT CHECK_LOCK ;Yes, see if need to lock
NOPE: CMP AH,6 ;Scroll up?
JNE TO_VIDEO_IO ;No, go to ROM routines
CHECK_LOCK:
INC SCROLL_COUNT ;Take care of scroll lock
MOV BH,MAX_LINES
CMP SCROLL_COUNT,BH ;Have we scrolled more than MAX_LINES?
JL TO_VIDEO_IO ;Nope, it's ok to scroll
;Yes, wait until a shift key is hit
MOV BL,BH ;Set SCROLL_COUNT to MAX_LINES-1
DEC BL ;so we can print one more line
MOV SCROLL_COUNT,BL
ASSUME DS:ROM_BIOS_DATA
MOV BX,ROM_BIOS_DATA
MOV DS,BX
LOOP: MOV BL,KB_FLAG ;Wait for left or right shift key push
TEST BL,10H ;Is scroll lock still on?
JZ TO_VIDEO_IO
AND BL,3 ;Pick off shift key info
JZ LOOP ;Stay in loop until shift key pressed
CMP BL,1 ;Right shift key pressed?
JE SCROLL_LINE ;Yes, allow scroll of one line
;No, must be left shift key, so reset scroll count
XOR BX,BX
MOV SCROLL_COUNT,BL
SCROLL_LINE:
TO_VIDEO_IO:
POP BX ;Restore BX register
PUSHF
CALL ROM_VIDEO_IO ;Perform a pseudo INT 10H call to BIOS
POP DS
IRET ;interrupt Return
INTERCEPT_VIDEO ENDP
;----------------------------------------------------------------------------;
;This routine intercepts all calls to KEYBOARD_IO
;If the keyboard function calls for a read (AH=0) then reset the scroll count
;----------------------------------------------------------------------------;
INTERCEPT_KEYBOARD PROC FAR
ASSUME CS:CSEG,DS:CSEG
STI ;Turn interrupts on
PUSH DS ;Save registers used by this routine
PUSH BX
MOV BX,CS ;Set up data segment for variables
MOV DS,BX
OR AH,AH ;Check to see if AH=0
JNZ KB1 ;Nope, branch to keyboard I/O
XOR BX,BX ;Yes, set scroll count to 0
MOV SCROLL_COUNT,BL
KB1: POP BX ;Restore BX register
ASSUME DS:NOTHING
POP DS
JMP ROM_KEYBOARD_IO ;Jump to keyboard routine and return
;directly to the routine that called
;this one
INTERCEPT_KEYBOARD ENDP
;----------------------------------------------------------------------------;
;This section of code saves the old interrupt vectors for the keyboard and
;video I/O routines. These vectors are replaced by the addresses of
;INTERCEPT_VIDEO and INTERCEPT_KEYBOARD PROCS above.
;----------------------------------------------------------------------------;
INIT_VECTORS PROC NEAR
ASSUME CS:CSEG,DS:CSEG
MOV AH,3 ;Set LAST_LINE to cursor line number
XOR BH,BH
INT 10H
MOV LAST_LINE,DH
ASSUME CS:CSEG,DS:VECTORS
MOV AX,VECTORS
MOV DS,AX
MOV AX,VIDEO_INT ;Save the ROM routine address
MOV ROM_VIDEO_IO,AX
MOV AX,VIDEO_INT[2]
MOV ROM_VIDEO_IO[2],AX
MOV AX,OFFSET INTERCEPT_VIDEO ;Set video INT 10H to point to
MOV VIDEO_INT,AX ;INTERCEPT_VIDEO PROC above.
MOV VIDEO_INT[2],CS
MOV AX,KEYBOARD_INT ;Save the ROM routine address
MOV ROM_KEYBOARD_IO,AX
MOV AX,KEYBOARD_INT[2]
MOV ROM_KEYBOARD_IO[2],AX
MOV AX,OFFSET INTERCEPT_KEYBOARD ;Set keyboard INT 16H to point
MOV KEYBOARD_INT,AX ;to INTERCEPT_KEYBOARD PROC
MOV KEYBOARD_INT[2],CS
MOV DX,OFFSET INIT_VECTORS ;End of resident portion
INT 27H ;Terminate but stay resident
INIT_VECTORS ENDP
CSEG ENDS
END BEGIN